﻿#ifndef DAABSTRACTNODEGRAPHICSITEM_H
#define DAABSTRACTNODEGRAPHICSITEM_H
#include "DAWorkFlowGlobal.h"
#include <QAbstractGraphicsShapeItem>
#include <QIcon>
#include "DANodeMetaData.h"
#include "DANodeLinkPoint.h"
#include "DAAbstractNode.h"
class DAAbstractNodeLinkGraphicsItem;
class DAAbstractNodeWidget;
DA_IMPL_FORWARD_DECL(DAAbstractNodeGraphicsItem)

/**
 * @brief 这是节点的基类，fastcae所有节点都继承此类
 * 作为一个节点的QGraphicsItem，此item应该由FCAbstractNode创建
 */
class DAWORKFLOW_API DAAbstractNodeGraphicsItem : public QAbstractGraphicsShapeItem
{
    DA_IMPL(DAAbstractNodeGraphicsItem)
    friend class FCAbstractNodeGraphicsFactory;
    friend class DAAbstractNodeLinkGraphicsItem;
    friend class FCNodeGraphicsScene;
    friend class DAAbstractNode;

public:
    enum { Type = DA::GraphicsNodeItem };
    int type() const { return (Type); }

public:
    DAAbstractNodeGraphicsItem(DAAbstractNode::SharedPointer n, QGraphicsItem *p = nullptr);
    virtual ~DAAbstractNodeGraphicsItem();

    DAAbstractNode *node();
    const DAAbstractNode *node() const;

    //获取node的名字
    QString getNodeName() const;

    //获取图标，图标是节点对应的图标
    QIcon getIcon() const;
    void setIcon(const QIcon &icon);

    //获取节点的元数据
    const DANodeMetaData &metaData() const;
    DANodeMetaData &metaData();

    //获取连接点
    const QList<DANodeLinkPoint> &getLinkPoints() const;

    //通过名字获取连接点
    DANodeLinkPoint getLinkPoint(const QString &name) const;

    //判断是否存在连接点
    bool isHaveLinkPoint(const DANodeLinkPoint &pl) const;

    //绘制连接点
    virtual void paintLinkPoints(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    //绘制某个连接点
    virtual void paintLinkPoint(const DANodeLinkPoint &pl, QPainter *painter);

    //获取连接点对应的矩形区域
    virtual QRect getlinkPointRect(const DANodeLinkPoint &pl) const;

    //获取节点对应的窗口，一般保存节点的设置
    DAAbstractNodeWidget *getNodeWidget() const;
    void setNodeWidget(DAAbstractNodeWidget *p);

    //重置连接点
    void resetLinkPoint();

    //节点的动作将会调用此函数，例如节点调用input，等参数会反应到item上面，就通过此函数进行反应，
    //通过重载此函数可以进行一些特殊的绘图
    virtual void nodeAction(int action, const QVariant &v);

protected:
    //处理一些联动事件，如和FCAbstractNodeLinkGraphicsItem的联动
    virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);

    //鼠标事件
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);

    //此函数用于FCAbstractNodeLinkGraphicsItem在调用attachedTo/From过程中调用
    bool recordLink(DAAbstractNodeLinkGraphicsItem *link, const DANodeLinkPoint &pl);

    //连接的link在销毁时调用，把item记录的link信息消除
    bool callItemLinkIsDestroying(DAAbstractNodeLinkGraphicsItem *link, const DANodeLinkPoint &pl);

    //生成linkpoint
    virtual QList<DANodeLinkPoint> generateLinkPoint() const;
};

#endif // FCNODEGRAPHICSITEM_H
